package com.chlitina.store.modules.sms.quartz;

import java.util.Calendar;
import java.util.Date;
import java.util.HashMap;
import java.util.List;

import org.hibernate.criterion.DetachedCriteria;
import org.hibernate.criterion.Restrictions;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import com.chlitina.store.common.utils.DateUtils;
import com.chlitina.store.common.utils.StoreCareUtils;
import com.chlitina.store.common.utils.StoreProductUtils;
import com.chlitina.store.modules.base.entity.Customer;
import com.chlitina.store.modules.base.entity.StoreCare;
import com.chlitina.store.modules.base.entity.StoreProduct;
import com.chlitina.store.modules.cash.model.Member;
import com.chlitina.store.modules.cash.model.MemberShoppingCart;
import com.chlitina.store.modules.cash.model.SolutionStoreCareCart;
import com.chlitina.store.modules.cash.model.SolutionStoreProductCart;
import com.chlitina.store.modules.expert.dao.CustomerSolutionAndCareDao;
import com.chlitina.store.modules.expert.dao.CustomerSolutionAndProductDao;
import com.chlitina.store.modules.expert.dao.CustomerSolutionDao;
import com.chlitina.store.modules.expert.entity.CustomerSolution;
import com.chlitina.store.modules.expert.entity.CustomerSolutionAndCare;
import com.chlitina.store.modules.expert.entity.CustomerSolutionAndProduct;
import com.chlitina.store.modules.expert.entity.StoreCustomerNotify;
import com.chlitina.store.modules.expert.service.StoreCustomerNotifyService;
import com.chlitina.store.modules.expert.utils.ExpertUtils;
import com.chlitina.store.modules.message.dao.StoreEmployeeTaskDao;
import com.chlitina.store.modules.message.entity.StoreEmployeeTask;
import com.chlitina.store.modules.sms.entity.SmsSendQueue;
import com.chlitina.store.modules.sms.entity.SmsTemplate;
import com.chlitina.store.modules.sms.service.SmsSendQueueService;
import com.chlitina.store.modules.sms.service.SmsSysCustomerService;
import com.chlitina.store.modules.sms.service.SmsTemplateService;
import com.chlitina.store.modules.sms.utils.SmsUtils;
import com.chlitina.store.modules.sys.dao.StoreDao;
import com.chlitina.store.modules.sys.entity.Store;
import com.chlitina.store.modules.sys.utils.StoreUtils;
import com.google.common.collect.Lists;

@Component
public class CustomerTipQueueGenerate {
	@Autowired
	protected SmsSendQueueService smsSendQueueService;
	@Autowired
	private SmsTemplateService smsTemplateService;
	@Autowired
	private StoreDao storeDao;
	@Autowired
	private SmsSysCustomerService smsSysCustomerService;
	@Autowired
	private StoreCustomerNotifyService storeCustomerNotifyService;

	@Autowired
	private CustomerSolutionDao customerSolutionDao;
	@Autowired
	private CustomerSolutionAndProductDao customerSolutionAndProductDao;
	@Autowired
	private CustomerSolutionAndCareDao customerSolutionAndCareDao;
	@Autowired
	private StoreEmployeeTaskDao storeEmployeeTaskDao;

	public CustomerTipQueueGenerate() {
	}

	public void generate(Member member) {
		Store store = StoreUtils.getStore();
		int ramainNum = store.getSms_remain_amount();
		MemberShoppingCart shoppingCart = member.getShoppingCart();
		if (shoppingCart.getSolutionProducts().isEmpty()
				&& shoppingCart.getSolutionCares().isEmpty()) {
			return;
		}

		String productTemplate = getSMSTemplate(SmsTemplate.SOLUTION_PRODUCT);
		String careTemplate = getSMSTemplate(SmsTemplate.SOLUTION_CARE);
		Customer customer = member.getCustomer();
		Long customerId = customer.getId();
		HashMap<String, String> temps = new HashMap<String, String>();
		temps.put("{customer}", customer.getName());
		temps.put("{store}", store.getName());
		int needNum = 0;
		List<SolutionStoreProductCart> solutionProducts = shoppingCart
				.getSolutionProducts();
		Long storeID = StoreUtils.getStore().getId();
		for (SolutionStoreProductCart solutionStoreProductCart : solutionProducts) {
			StoreProduct storeProduct = solutionStoreProductCart
					.getStoreProduct();
			String product = StoreProductUtils.getName(storeProduct);
			temps.put("{product}", product);
			long solutionID = solutionStoreProductCart.getSolutionID();
			CustomerSolution customerSolution = customerSolutionDao
					.findOne(solutionID);
			CustomerSolutionAndProduct container = customerSolutionAndProductDao
					.findByPKId(solutionID, storeProduct.getId());
			if (container == null) {
				System.err
						.println("No CustomerSolutionAndProduct Found by solutionID= "
								+ solutionID
								+ ", storeProduct= "
								+ storeProduct.getId());
				continue;
			}
			String employeeTask="客户所用产品【" + product + "】在" + SmsUtils.PRODUCT_TIP_DAYS
					+ "天后即将用完，请及时跟踪客户";
			// findQueTable
			if (solutionStoreProductCart.isAppend()) {
				// append
				Date oldNotifyDate = container.getNotifyDate();
				// care amount
				int addAmount = solutionStoreProductCart.getCount();
				int offday = ExpertUtils.getMixProductDuration(container,
						addAmount);

				// update CustomerSolutionAndProduct's amount and notifyDate
				container.setAmount(container.getAmount() + addAmount);
				Date currentNotifyDate = oldNotifyDate;
				if (offday > 0) {
					currentNotifyDate = DateUtils
							.addDays(oldNotifyDate, offday);
				}
				container.setNotifyDate(currentNotifyDate);
				customerSolutionAndProductDao.save(container);
				if (offday < 0) {
					System.err
							.println("Error state Product takes day is invalid");
					continue;
				}
	
				// update StoreCustomerNitify
				List<StoreCustomerNotify> notify = storeCustomerNotifyService
						.findNotSendBySolutionProduct(storeID, oldNotifyDate,
								oldNotifyDate, customerId, solutionID,
								storeProduct.getId());
				if (notify.size() > 0) {
					//update
					StoreCustomerNotify storeCustomerNotify = notify.get(0);
					SmsSendQueue smsSendQueue = storeCustomerNotify
							.getSmsSendQueue();
					smsSendQueue.setPlanSendTime(currentNotifyDate);
					smsSendQueueService.save(smsSendQueue);
					storeCustomerNotify.setNotifyDate(currentNotifyDate);
					storeCustomerNotifyService.save(storeCustomerNotify);

				} else {
					//add new
					String message = replaceTemplate(productTemplate, temps);
					SmsSendQueue queue = createQueue(currentNotifyDate,
							customer.getMobile(), message);
					createNotify(currentNotifyDate, customerSolution,
							storeProduct, null, queue, message);
					needNum += getSmsNum(message.length());
					System.err
							.println("Error state for StoreCustomerNotify find by Solution Product");
				}
				//update employee task
				StoreEmployeeTask storeEmployeeTask = findStoreEmployeeTask(oldNotifyDate, customerSolution, employeeTask);
				if(storeEmployeeTask!=null){
					storeEmployeeTask.setTaskDate(currentNotifyDate);
					storeEmployeeTaskDao.save(storeEmployeeTask);
				}else{
					createEmployeeTast(currentNotifyDate, customerSolution, employeeTask);
				}

			} else {
				// new Create
				String message = replaceTemplate(productTemplate, temps);
				SmsSendQueue queue = createQueue(container.getNotifyDate(),
						customer.getMobile(), message);
				createNotify(container.getNotifyDate(), customerSolution,
						storeProduct, null, queue, message);
				createEmployeeTast(container.getNotifyDate(), customerSolution, employeeTask);
				System.out.println(message);
				needNum += getSmsNum(message.length());
			}
		}

		List<SolutionStoreCareCart> solutionCares = shoppingCart
				.getSolutionCares();
		for (SolutionStoreCareCart solutionStoreCareCart : solutionCares) {
			StoreCare storeCare = solutionStoreCareCart.getStoreCare();
			String care = StoreCareUtils.getName(storeCare);
			temps.put("{care}", care);
			String message = replaceTemplate(careTemplate, temps);
			long solutionID = solutionStoreCareCart.getSolutionID();
			if (solutionStoreCareCart.isAppend()) {

			} else {
				CustomerSolution customerSolution = customerSolutionDao
						.findOne(solutionID);
				CustomerSolutionAndCare container = customerSolutionAndCareDao
						.findByPKId(solutionID, storeCare.getId());
				if (container == null) {
					System.err
							.println("NO CustomerSolutionAndCare Found by solutionID= "
									+ solutionID
									+ ", storeCare= "
									+ storeCare.getId());
					continue;
				}
				SmsSendQueue queue = createQueue(container.getNotifyDate(),
						customer.getMobile(), message);
				createNotify(container.getNotifyDate(), customerSolution, null,
						storeCare, queue, message);
				createEmployeeTast(container.getNotifyDate(), customerSolution,
						"客户将于明天到店做【" + care + "】，请及时跟踪客户");
				needNum += getSmsNum(message.length());
				System.out.println(message);
			}

		}

		System.out.println(needNum);
		if (ramainNum < needNum) {
			return;
		} else {
			ramainNum -= needNum;
		}
		store.setSms_remain_amount(ramainNum);
		storeDao.save(store);

	}

	private StoreEmployeeTask findStoreEmployeeTask(Date date,
			CustomerSolution customerSolution, String message) {
		DetachedCriteria dc = storeEmployeeTaskDao.createDetachedCriteria();
		dc.add(Restrictions.eq("store.id", customerSolution.getStore().getId()));
		dc.add(Restrictions.eq("completed", 0));
		Date begin = DateUtils.getBeginOfDay(date);
		Date end = DateUtils.getEndOfDay(date);
		dc.add(Restrictions.between("taskDate", begin, end));
		dc.createAlias("employee", "e");
		dc.add(Restrictions.eq("taskContent", message));
		dc.add(Restrictions.eq("customer.id", customerSolution.getCustomer()
				.getId()));
		List<StoreEmployeeTask> find = storeEmployeeTaskDao.find(dc);
		if (find.isEmpty()) {
			return null;
		}
		return find.get(0);
	}

	private void createEmployeeTast(Date notifyDate,
			CustomerSolution customerSolution, String message) {
		StoreEmployeeTask task = new StoreEmployeeTask();
		task.setCustomer(customerSolution.getCustomer());
		task.setEmployee(customerSolution.getEmployee());
		task.setStore(StoreUtils.getStore());
		task.setTaskContent(message);
		task.setType(StoreEmployeeTask.TYPE_PRODUCT_OR_CARE);
		task.setCompleted(StoreEmployeeTask.STATUS_NOT_COMPLETED);
		task.setViewed(StoreEmployeeTask.STATUS_NOT_VIEWED);
		task.setTaskDate(notifyDate);
		storeEmployeeTaskDao.save(task);
	}

	private void createNotify(Date notifyDate,
			CustomerSolution customerSolution, StoreProduct storeProduct,
			StoreCare storeCare, SmsSendQueue smsSendQueue, String message) {
		StoreCustomerNotify log = new StoreCustomerNotify();
		log.setStore(StoreUtils.getStore());
		log.setCustomer(customerSolution.getCustomer());
		log.setContent(message);
		log.setEmployee(customerSolution.getEmployee());
		log.setStoreCare(storeCare);
		log.setStoreProduct(storeProduct);
		log.setSmsSendQueue(smsSendQueue);
		log.setNotifyDate(notifyDate);
		log.setCustomerSolution(customerSolution);
		storeCustomerNotifyService.save(log);

	}

	/**
	 * 加载log 和详细信息所需的字段
	 * 
	 * @param store
	 * @param sendTime
	 * @param content
	 */
	public void generate(List<CustomerSolution> customerSolutionList) {
		Store store = StoreUtils.getStore();
		Calendar cal = Calendar.getInstance();
		int ramainNum = store.getSms_remain_amount();
		if (customerSolutionList.size() == 0) {
			return;
		}
		String template = getSMSTemplate(SmsTemplate.CUSTOMER_CONFIRM);
		Customer customer = customerSolutionList.get(0).getCustomerExam()
				.getCustomer();
		List<String> expireProductList = Lists.newArrayList();
		List<String> expireCareList = Lists.newArrayList();
		for (CustomerSolution cs : customerSolutionList) {
			getListBySolution(cs, expireProductList, expireCareList);
		}
		String message = replaceTemplate(template, store.getName(),
				customer.getName(), expireProductList, expireCareList);
		int needNum = getSmsNum(message.length());
		if (ramainNum < needNum) {
			return;
		} else {
			ramainNum -= needNum;
		}
		createQueue(cal.getTime(), customer.getMobile(), message);
		store.setSms_remain_amount(ramainNum);
		storeDao.save(store);
	}

	public void immediateSend(String mobile, String message) {
		Store store = StoreUtils.getStore(true);
		int ramainNum = store.getSms_remain_amount();
		int needNum = getSmsNum(message.length());
		if (ramainNum < needNum) {
			return;
		} else {
			ramainNum -= needNum;
		}
		createQueue(DateUtils.appendSeconds(70), mobile, message);
		store.setSms_remain_amount(ramainNum);
		storeDao.save(store);
	}

	public void getListBySolution(CustomerSolution customerSolution,
			List<String> tipProductList, List<String> tipCareList) {
		List<CustomerSolutionAndProduct> productList = customerSolution
				.getProductList();
		for (CustomerSolutionAndProduct customerSolutionAndProduct : productList) {
			StoreProduct storeProduct = customerSolutionAndProduct
					.getStoreProduct();
			String name = "";
			if (storeProduct.getProduct_type() == StoreProduct.TYPE_SYS) {
				name = storeProduct.getProduct().getName();
			} else {
				name = storeProduct.getStoreSelfProduct().getName();
			}
			tipProductList.add(name);
		}
		List<CustomerSolutionAndCare> careList = customerSolution.getCareList();
		for (CustomerSolutionAndCare customerSolutionAndCare : careList) {
			StoreCare storeCare = customerSolutionAndCare.getStoreCare();
			String name = "";
			if (storeCare.getCare_type() == StoreCare.TYPE_SYS) {
				name = storeCare.getCare().getName();
			} else {
				name = storeCare.getStoreSelfCare().getName();
			}
			tipCareList.add(name);
		}
	}

	public int getSmsNum(int length) {
		return length / SmsUtils.default_length + 1;
	}

	// 尊贵的克丽缇娜会员{customer}，您购买了产品{product-list}，护理{care-days}，{store}
	public String replaceTemplate(String template, String store,
			String customer, List<String> tipProductList,
			List<String> tipCareList) {
		template = template.replace("{customer}", customer);
		template = template
				.replace("{product-list}", tipProductList.toString());
		template = template.replace("{care-list}", tipCareList.toString());
		template = template.replace("{store}", store);
		return template;
	}

	public String replaceTemplate(String template,
			HashMap<String, String> values) {
		for (String key : values.keySet()) {
			template = template.replace(key, values.get(key));
		}
		return template;
	}

	public String getSMSTemplate(String code) {
		return smsTemplateService.getByCode(code).getTemplate();
	}

	public SmsSendQueue createQueue(Date time, String phone, String content) {
		SmsSendQueue sms = new SmsSendQueue();
		sms.setMobile(phone);
		sms.setContent(content);
		sms.setStatus(SmsSendQueue.WAIT_STATUS);
		sms.setPlanSendTime(time);
		smsSendQueueService.save(sms);
		return sms;
	}

}
